package controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"path/filepath"
	"skapp/pkg/logger"
	"skapp/pkg/utils/errorx"
	"skapp/pkg/utils/response"
)

type GetPathDto struct {
	// 路径
	Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
}

type GetFileDto struct {
	// 路径
	Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
	// 偏移量
	Offset int64 `form:"offset"`
	// 区块大小
	ChunkSize int64 `form:"chunkSize"`
}

// GetPath
// @Summary      获取文件路径
// @Description  获取文件路径
// @Tags         File
// @Accept       json
// @Produce      json
// @Param		vo query controller.GetPathDto true "获取文件路径"
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /file/path [get]
func GetPath(ctx *gin.Context) {
	dto := &GetPathDto{}
	err := ctx.ShouldBindQuery(dto)
	if err = errorx.ParseError(err); err != nil {
		logger.Log.Errorln(err)
		ctx.JSON(200, err)
	}
	logger.Log.Infof("%+v", dto)

	absPath, _ := filepath.Abs(dto.Path)
	ctx.JSON(200, response.NewResponse(absPath))
}

// GetFile
// @Summary      获取文件
// @Description  获取文件
// @Tags         File
// @Accept       json
// @Produce      octet-stream
// @Param		vo query controller.GetFileDto true "获取文件"
// @Router       /file/get [get]
func GetFile(ctx *gin.Context) {
	dto := &GetFileDto{}
	err := ctx.BindQuery(dto)
	if err != nil {
		ctx.Status(http.StatusInternalServerError)
		logger.Log.Errorln(err)
		return
	}

	offset := dto.Offset
	chunkSize := dto.ChunkSize

	p, _ := filepath.Abs(dto.Path)
	info, err := os.Stat(p)
	if err != nil || info.IsDir() {
		ctx.Status(http.StatusNotFound)
		return
	}

	if offset == 0 && chunkSize == 0 {
		ctx.File(p)
		return
	} else {
		w := ctx.Writer
		ctx.Request.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+chunkSize))
		logger.Log.Debugf("%s", ctx.Request.Header.Get("Range"))
		http.ServeFile(w, ctx.Request, p)
		return
	}
}

// SaveFile
// @Summary      保存文件
// @Description  保存文件
// @Tags         File
// @Accept       multipart/form-data
// @Produce      json
// @Param		fileContent formData file true "文件内容"
// @Param		fileName formData string true "文件名"
// @Router       /file/save [get]
func SaveFile(ctx *gin.Context) {
	// 1.获取文件名
	fileName := ctx.PostForm("fileName")

	// 2.获取文件内容
	fileContent, _ := ctx.FormFile("fileContent")
	err := ctx.SaveUploadedFile(fileContent, fileName)
	if err != nil {
		ctx.JSON(500, errorx.NewDefaultError(err.Error()))
		return
	} else {
		ctx.JSON(200, response.NewResponse(fmt.Sprintf("保存成功")))
	}
}
